package com.lynn.blog.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.crypto.SecureUtil;
import com.lynn.blog.dto.RegisterDTO;
import com.lynn.blog.util.JwtUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.lynn.blog.entity.User;
import com.lynn.blog.mapper.UserMapper;
import com.lynn.blog.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.Instant;

/**
 * 服务层实现。
 *
 * @author root
 * @since 2024-07-15
 */
@Transactional(rollbackFor = Exception.class)
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    private static final String SALT = "lynn";

    @Override
    public String register(RegisterDTO dto) {
        QueryWrapper wrapper = new QueryWrapper().eq(User::getUsername, dto.getUsername());
        User dbUser =  this.getOne(wrapper);
        if (dbUser != null){
            throw new RuntimeException("用户名已存在");
        }

        dto.setPassword(md5(dto.getPassword()));

        User user = new User();
        BeanUtil.copyProperties(dto, user);
        user.setCreated(Timestamp.from(Instant.now()));
        user.setLastModified(Timestamp.from(Instant.now()));

        if (this.save(user)){
            return JwtUtil.generateToken(Long.valueOf(user.getUserId()), user.getUsername());
        }
        return null;
    }

    @Override
    public String login(String username, String password) {
        QueryWrapper wrapper = new QueryWrapper().eq(User::getUsername, username);
        User user = this.getOne(wrapper);
        if (user != null) {
            if (user.getPassword().equals(md5(password))) {
                return JwtUtil.generateToken(Long.valueOf(user.getUserId()), user.getUsername());
            }
        }
        throw new RuntimeException("用户名或密码错误");
    }

    // MD5 加密
    private String md5(String password) {
        return SecureUtil.md5(password + SALT);
    }
}
